/**
 * Created by YangYan on 2016/5/22.
 */

(function () {
    function Complex(real,imaginary) {
        if(isNaN(real) || isNaN(imaginary)){//isNaN 判断不为数字
            throw new TypeError();
        };
        this.r=real;
        this.i=imaginary;
    };
    Complex.prototype.add=function (that) {
        return new Complex(this.r+that.r,this.i+that.i);
    };
    Complex.prototype.mul=function (that) {
        return new Complex(this.r*that.r-this.i*that.i,this.r*that.i+this.r*that.i);
    };
    Complex.prototype.mag=function(){
        return Math.sqrt(this.r*this.r+this.i*this.i);
    };
    Complex.prototype.neg=function () {
        return new Complex(-this.r,-this.i);
    };
    Complex.prototype.equals=function(that){
        return that!=null &&that.constructor ===Complex &&this.r===that.r &&this.i==that.i;
    };

    Complex.ZERO=new Complex(0,0);
    Complex.ONE=new Complex(1,0);
    Complex.I=new Complex(0,1);

    Complex.parse=function(s){
      try{
          var m=Complex._format.exec(s);
          //console.log(m);
          return new Complex(parseFloat(m[1]),parseFloat(m[2]));
      }catch(x){
          throw new TypeError("Can't parse" +s+" as a complex number.")
      }
    };


    Complex._format=/^\{([^,]+),([^}]+)\}$/;//下划线代表是在类内部使用

    var c=new Complex(2,3);
    var d=new Complex(c.i,c.r);
   // console.log(c.add(d).toString());
    //Complex.parse(c.toString()).add(c.neg()).equals(Complex.ZERO);
   //-----------------------------------------------------------------
    Number.prototype.times=function (f,context){
        var n=Number(this);
        for(var i=0;i<n;i++) f.call(context,i);
    };
    var n=3;
    n.times(function(n){console.log(n+":hello")});

    String.prototype.trim=String.prototype.trim || function(){
            if(!this) return this;
            return this.replace(/^\s+|\s+$/g),"";
        };

    Function.prototype.getName=function(){
        return this.name || this.toString().match(/function\s*([^()*]\(/)[1];
    };
//----------------------------------------------------------------------------
    //上下文的问题
    var o={
        x:23,
        m:function(){
            var x=1;
            console.log(x,this.x);
            console.log(this)
        }
    };
    o.m();

    var o1={
        x:23,
        m:function (){
            var x=1;
            var f=function (){
                //console.log(x,this.x);
                //console.log(this)
            };
            f()
        }
    };
    o1.m();//上下文是基于对象的，所以函数f()不能获取对象o的执行上下文,//1,undefined

    var C=function(){};
    C.prototype={
        x:23,
        m:function(){
            var x=1;
            var f=function () {
                //console.log(x,instance1.x);
            }
            f();
        }
    };
    var instance1=new C();
    instance1.m();//1,23

    var C1=function(){};
    C1.prototype={
        x:10,
        m:function () {
            var x=1;
            this.f();
        },
        f:function(){
           // console.log(x,this.x);
        }
    };
    var instance2=new C1();
    instance2.m();//方法f()不能获取方法m()的作用域，所以变量x不在方法f()

    var C2=function(){};
    C2.prototype={
        x:23,
        m:function(){
            var x=1;
            console.log(this);
            this.f=function(){
                console.log(x,this.x);
                console.log(this);
            };
            this.f();
        }
    };
    var instance3=new C2();
    instance3.m();//1,23

    var o2={
        x:23,
        onTimeout:function () {
            console.log("x:",this.x);
        },
        m:function(){
            var self=this;
            console.log(this);
            setTimeout(function () {
                self.onTimeout();
                console.log(self);
                console.log(this);
            },1);
        }
    };
    o2.m();//我们通过临时变量self保存了this的引用，由于setTimeout()函数可以获取m()的作用域

})()
